#pragma once

#include <iostream>
#include <functional>
#include <string>
#include <memory>
#include "Socket.hpp"
#include "InetAddr.hpp"
#include "Protocol.hpp"
#include "ThreadPool.hpp"

using namespace Socket_ns;

class TCPServer;
// 线程数据的封装
class ThreadData
{
public:
    ThreadData(socket_sptr sockfd, const InetAddr &clientAddr, TCPServer *self)
        : _sockfd(sockfd), _clientAddr(clientAddr), _self(self)
    {
    }

public:
    socket_sptr _sockfd;
    InetAddr _clientAddr;
    TCPServer *_self;
};

// 服务器进行服务的函数类型，由外部传入函数对象完成
using service_t = std::function<void()>;

class TCPServer
{
private:
    static void *HandlerSock(void *arg)
    {
        // 线程自己分离
        pthread_detach(pthread_self());

        ThreadData *td = static_cast<ThreadData *>(arg);
        // 执行
        td->_self->_service();

        delete td;
        return nullptr;
    }

public:
    TCPServer(int port)
        : _serverAddr("0", port),
          _listenSock(std::make_unique<TCPSocket>()),
          _isRunning(false)
    {
        _listenSock->BuildListenSocket(_serverAddr);
        CallBack call;
    }

    void Loop()
    {
        while (true)
        {
            InetAddr clientAddr;
            socket_sptr fd = _listenSock->Accepter(&clientAddr);
            if (nullptr == fd)
                continue;

            LOG(DEBUG, "_sock:%d", fd->SockFd());
            CallBack call;
            _service = std::bind(&CallBack::HandlerRequest, &call, fd->SockFd());

            // 1.创建线程执行任务
            // pthread_t t;
            // ThreadData *td = new ThreadData(fd, clientAddr, this);
            // pthread_create(&t, nullptr, HandlerSock, td);
            // LOG(DEBUG, "一个请求");

            // 2.使用线程池执行任务
            ThreadPool<service_t>::GetInstance()->Push(_service);
        }
    }

    ~TCPServer()
    {
    }

private:
    bool _isRunning;
    InetAddr _serverAddr;
    std::unique_ptr<Socket> _listenSock;
    service_t _service;
};